package com.scau402.system1.domain.factory;

import com.scau402.system1.domain.bo.WmsJadeFeatureBO;
import com.scau402.system1.domain.bo.WmsJadeImageBO;
import com.scau402.system1.domain.bo.WmsJadeTypeBO;
import com.scau402.system1.domain.po.WmsJadeFeaturePO;
import com.scau402.system1.domain.po.WmsJadeImagePO;
import com.scau402.system1.domain.po.WmsJadePO;
import com.scau402.system1.domain.bo.WmsJadeBO;
import com.scau402.system1.domain.po.WmsJadeTypePO;
import com.scau402.system1.domain.query.InboundJadeQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 翡翠实体工厂
 *
 * @author
 * @create 2024/1/2 23:21
 * @description
 */
@Component
@Slf4j
public class WmsJadeFactory {

    public WmsJadeBO toWmsJadeBO(WmsJadePO wmsJadePO, WmsJadeTypeBO wmsJadeTypeBO, List<WmsJadeFeatureBO> wmsJadeFeatureBOList) {
        return Optional.ofNullable(wmsJadePO)
                .map(po -> {
                    WmsJadeBO wmsJadeBO = new WmsJadeBO();
                    BeanUtils.copyProperties(po, wmsJadeBO);
                    Optional.ofNullable(wmsJadeTypeBO).ifPresent(wmsJadeBO::setJadeTypeBO);
                    Optional.ofNullable(wmsJadeFeatureBOList).ifPresent(wmsJadeBO::setJadeFeatureBOList);
                    return wmsJadeBO;
                })
                .orElse(null);
    }

    public WmsJadeImageBO toWmsJadeImageBO(WmsJadeImagePO po) {
        return Optional.ofNullable(po)
                .map(p -> {
                    WmsJadeImageBO wmsJadeImageBO = new WmsJadeImageBO();
                    BeanUtils.copyProperties(p, wmsJadeImageBO);
                    return wmsJadeImageBO;
                })
                .orElse(null);
    }

    public WmsJadeFeatureBO toWmsJadeFeatureBO(WmsJadeFeaturePO featurePO, WmsJadeImagePO imagePO) {
        return Optional.ofNullable(featurePO)
                .map(p -> {
                    WmsJadeFeatureBO wmsJadeFeatureBO = new WmsJadeFeatureBO();
                    BeanUtils.copyProperties(p, wmsJadeFeatureBO);
                    Optional.ofNullable(imagePO).ifPresent(i -> wmsJadeFeatureBO.setWmsJadeImageBO(toWmsJadeImageBO(i)));
                    return wmsJadeFeatureBO;
                })
                .orElse(null);
    }

    /**
     * 将数据库中的翡翠类型PO转换为BO，但是未设置子类型
     *
     * @param po
     * @return
     */
    public WmsJadeTypeBO toRawWmsJadeTypeBO(WmsJadeTypePO po) {
        return Optional.ofNullable(po)
                .map(p -> {
                    WmsJadeTypeBO wmsJadeTypeBO = new WmsJadeTypeBO();
                    BeanUtils.copyProperties(p, wmsJadeTypeBO);
                    return wmsJadeTypeBO;
                })
                .orElse(null);
    }

    /**
     * 将数据库中的翡翠类型PO转换为完整BO
     *
     * @param poList
     * @return
     */
    public Map<Long, WmsJadeTypeBO> toJadeTypeBOMap(List<WmsJadeTypePO> poList) {
        List<WmsJadeTypeBO> wmsJadeTypeBOList = Optional.ofNullable(poList)
                .orElse(new ArrayList<>(0))
                .stream()
                .map(this::toRawWmsJadeTypeBO)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        log.info("查询得到{}条翡翠品类", wmsJadeTypeBOList.size());

        // 把parentId相同的放在一起，然后转换成map，key为parentId，value为list，并且list中的元素按照orderNum升序排序
        Map<Long, List<WmsJadeTypeBO>> jadeTypeBOMap = wmsJadeTypeBOList
                .stream()
                .collect(Collectors.groupingBy(WmsJadeTypeBO::getParentId, Collectors.toList()))
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream().sorted(Comparator.comparing(WmsJadeTypeBO::getOrderNum)).collect(Collectors.toList())));

        wmsJadeTypeBOList.forEach(wmsJadeTypeBO -> {
            if (jadeTypeBOMap.containsKey(wmsJadeTypeBO.getId())) {
                wmsJadeTypeBO.setChildren(jadeTypeBOMap.get(wmsJadeTypeBO.getId()));
                log.info("翡翠id为{}，名称为{}的品类有{}个子品类", wmsJadeTypeBO.getId(), wmsJadeTypeBO.getJadeTypeName(), jadeTypeBOMap.get(wmsJadeTypeBO.getId()).size());
            }
        });

        Map<Long, WmsJadeTypeBO> resultMap = wmsJadeTypeBOList
                .stream()
                .collect(Collectors.toMap(WmsJadeTypeBO::getId, Function.identity()));

        log.info("初始化翡翠品类BO缓存成功， 共{}条", resultMap.size());

        return resultMap;
    }

    public List<WmsJadeFeatureBO> toWmsJadeFeatureBOList(List<WmsJadeFeaturePO> jadeFeaturePOList, Map<Long, WmsJadeImageBO> jadeImageBOMap) {
        return Optional.ofNullable(jadeFeaturePOList)
                .orElse(new ArrayList<>(0))
                .stream()
                .map(jadeFeaturePO -> toWmsJadeFeatureBO(jadeFeaturePO, jadeImageBOMap.get(jadeFeaturePO.getImageId())))
                .collect(Collectors.toList());
    }

    public WmsJadeFeatureBO toWmsJadeFeatureBO(WmsJadeFeaturePO jadeFeaturePO, WmsJadeImageBO jadeImageBO) {
        return Optional.ofNullable(jadeFeaturePO)
                .map(jadeFeature -> {
                    WmsJadeFeatureBO jadeFeatureBO = new WmsJadeFeatureBO();
                    BeanUtils.copyProperties(jadeFeature, jadeFeatureBO);
                    jadeFeatureBO.setWmsJadeImageBO(jadeImageBO);
                    return jadeFeatureBO;
                })
                .orElse(null);
    }

    public WmsJadePO toWmsJadePO(InboundJadeQuery query) {
        return Optional.ofNullable(query)
                .map(q -> {
                    WmsJadePO wmsJadePO = new WmsJadePO();
                    BeanUtils.copyProperties(q, wmsJadePO);
                    return wmsJadePO;
                })
                .orElse(null);
    }
}
